/**
 * 
 */
package org.vsg.common.pagination.datatrans;

import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.vsg.common.pagination.carrier.CollectionCarrier;
import org.vsg.common.pagination.carrier.GroupingValueCarrier;
import org.vsg.common.pagination.carrier.RecordLimitCarrier;
import org.vsg.common.pagination.carrier.ValueCarrier;
import org.vsg.common.pagination.carrier.WebCarrier;
import org.vsg.common.pagination.keyword.PaginationKeyword;
import org.vsg.common.pagination.sort.SingleSort;
import org.vsg.common.pagination.sort.SortField;

/**
 * @author vison bill
 *
 */
public class PaginationProviderFactory {
	
	private static final PaginationProviderFactory factory = new PaginationProviderFactory();
	
	private final static Logger logger = LoggerFactory.getLogger(PaginationProviderFactory.class);
	
	protected PaginationProviderFactory() {
		
	}
	
	// get the factory instance
	public static PaginationProviderFactory getInstance() {
		return factory;
	}
	
	public PaginationProvider generateProvider(ValueCarrier valueCarrier) {
		
	
		GenericPaginationProvider provider = new GenericPaginationProvider();
		
		GenericDataTransformer transformer = new GenericDataTransformer();
		
		int pageIndex = 0;
		
		if (valueCarrier.getPageIndex() < 0) {
			logger.info("PageIndex pointed to is less than zero!");
		} else {
			pageIndex = valueCarrier.getPageIndex();
		}
		int dataOffset = pageIndex * valueCarrier.getPageSize();
		
		transformer.setImplicitValue(PaginationKeyword.TFS_DATA_OFFSET ,new Integer(dataOffset) );
		transformer.setImplicitValue(PaginationKeyword.TFS_ROWS , new Integer(valueCarrier.getPageSize()));
		transformer.setImplicitValue(PaginationKeyword.TFS_CARRIER , valueCarrier);
		
		// get the ValueCarrier Type
		// ------------------------------------------ advance pagination vc
		
		// --- get collection value setting , support collection carier
		if ( valueCarrier instanceof CollectionCarrier ) {
			CollectionCarrier vcc = (CollectionCarrier)valueCarrier;
			handle(vcc , transformer);
		}
		
		if (valueCarrier instanceof WebCarrier) {
			WebCarrier wc = (WebCarrier)valueCarrier;
			handle(wc , transformer);
		}
		
		if (valueCarrier instanceof SingleSort) {
			SingleSort svc = (SingleSort)valueCarrier;
			handle(svc , transformer);
		}
		
		// :did not test:
		if (valueCarrier instanceof GroupingValueCarrier) {
			GroupingValueCarrier avc = (GroupingValueCarrier)valueCarrier;
			transformer.setImplicitValue(PaginationKeyword.TFS_GROUPING_SIZE , new Integer(avc.getGroupingSize()));
		}
		
		// inject data transformer
		provider.setDataTransformer(transformer);
		
		return provider;
	}
	
	public PaginationProvider generateProvider(RecordLimitCarrier limitCarrier) {
		GenericPaginationProvider provider = new GenericPaginationProvider();
		
		GenericDataTransformer transformer = new GenericDataTransformer();

		int dataOffset = limitCarrier.getStartIndex();
		
		transformer.setImplicitValue(PaginationKeyword.TFS_DATA_OFFSET ,new Integer(dataOffset) );
		transformer.setImplicitValue(PaginationKeyword.TFS_ROWS , new Integer( limitCarrier.getLimit() ));
		transformer.setImplicitValue(PaginationKeyword.TFS_CARRIER , limitCarrier);
		// get the ValueCarrier Type
		// ------------------------------------------ advance pagination vc
		
		// get collection value setting
		if (limitCarrier instanceof CollectionCarrier) {
			CollectionCarrier vcc = (CollectionCarrier)limitCarrier;
			handle(vcc , transformer);
		}
		
		if (limitCarrier instanceof WebCarrier) {
			WebCarrier wc = (WebCarrier)limitCarrier;
			handle(wc , transformer);			
		
		}
		
		if (limitCarrier instanceof SingleSort) {
			SingleSort svc = (SingleSort)limitCarrier;
			handle(svc , transformer);
		}
		
		// inject data transformer
		provider.setDataTransformer(transformer);
		
		return provider;		
	}
	
	// ---- defind the value ----
	private void handle(CollectionCarrier vcc ,AbstractDataTransformer transformer) {
		transformer.setValue(PaginationKeyword.TFS_ARRAYALLLIST , vcc.getDataList());
	}
	
	private void handle(SingleSort svc , AbstractDataTransformer transformer) {
		
		Collection<SortField> coll = new Vector<SortField>();
		if (svc.getSortField() != null) {
			coll.add(svc.getSortField());
		}			
		transformer.setImplicitValue(PaginationKeyword.TFS_SORTBY , coll);		
	}
	
	private void handle(WebCarrier wc , AbstractDataTransformer transformer) {
		
		Set paramKeys = wc.getParameterNames();
		String key = null;
		for (Iterator iter = paramKeys.iterator() ; iter.hasNext() ;) {
			key = (String)iter.next();
			
			// is no check properties
			Object value = wc.getParameterObject( key );
			
			// --- check the value is String Array

			transformer.setValue(key , value);
		}		
	}
	
	
}
